import java.util.*;
/**
 * K个一组反转链表
 * 将链表每K个节点分为一组，反转每组内的节点
 * 如果最后剩余的节点数不足K个，则保持原顺序
 * 时间复杂度O(n)，空间复杂度O(1)
 */
public class reverseKGroup {
    /**
     * 链表节点类
     * 包含节点值和指向下一个节点的引用
     */
    public static class ListNode{
        int val;        // 节点值
        ListNode next;  // 指向下一个节点的引用
        
        // 无参构造函数
        ListNode(){}
        
        // 带值的构造函数
        ListNode(int val){
            this.val = val;
        }
        
        // 带值和下一个节点的构造函数
        ListNode(int val, ListNode next){
            this.val = val;
            this.next = next;
        }
    }

    /**
     * K个一组反转链表的方法
     * 算法步骤：
     * 1. 计算链表长度
     * 2. 每次处理K个节点：
     *    - 反转当前K个节点
     *    - 将反转后的子链表与前后节点连接
     *    - 更新指针位置，处理下一组
     * 
     * @param head 链表头节点
     * @param k 每组节点个数
     * @return 反转后的链表头节点
     */
    public static ListNode reverseKGroupM(ListNode head, int k){
        // 处理特殊情况：空链表、单节点链表、k为0
        if(head == null || head.next == null || k == 0) return head;
        
        // 创建虚拟头节点，简化操作
        ListNode dummy = new ListNode(-1);
        dummy.next = head;
        
        // 计算链表长度
        ListNode cur = dummy.next;
        int len = 0;
        while(cur != null){
            len++;
            cur = cur.next;
        }
        
        // 初始化指针
        ListNode pre = null;      // 用于反转时的前一个节点
        ListNode tmp = null;      // 用于保存下一个节点
        cur = dummy.next;         // 当前处理的节点
        ListNode preKHead = dummy;  // 当前K个节点的前一个节点
        ListNode kTail = null;    // 当前K个节点的尾节点
        
        // 当剩余节点数大于等于K时，继续处理
        while(len >= k){
            // 反转当前K个节点
            for(int i = 0; i < k; i++){
                tmp = cur.next;    // 保存下一个节点
                cur.next = pre;    // 反转当前节点的指向
                pre = cur;         // 移动pre指针
                cur = tmp;         // 移动cur指针
            }
            
            // 将反转后的子链表与前后节点连接
            kTail = preKHead.next;  // 保存当前K个节点的尾节点
            preKHead.next = pre;    // 将前一个节点连接到反转后的头节点
            kTail.next = cur;       // 将反转后的尾节点连接到下一个节点
            
            // 更新指针位置，准备处理下一组
            preKHead = kTail;       // 更新下一组的前一个节点
            len = len - k;          // 更新剩余节点数
        }
        
        return dummy.next;  // 返回反转后的链表头节点
    }

    /**
     * 主函数：处理输入输出
     * 输入格式：
     * 第一行：链表节点值，用空格分隔
     * 第二行：每组节点个数k
     */
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        // 读取链表节点值
        String[] s = sc.nextLine().split(" ");
        // 读取每组节点个数
        int k = sc.nextInt();
        sc.nextLine();  // 消耗换行符
        
        // 创建链表
        ListNode dummy = new ListNode(-1);  // 虚拟头节点
        ListNode node = dummy;
        for(int i = 0; i < s.length; i++){
            node.next = new ListNode(Integer.parseInt(s[i]));
            node = node.next;
        }
        
        // 执行K个一组反转并输出结果
        ListNode result = reverseKGroupM(dummy.next, k);
        while(result != null){
            System.out.print(result.val + " ");
            result = result.next;
        }
        sc.close();
    }
}
